import axios from 'axios'
import API_CONFIG from './apiConfig.js'
import logger from '../utils/logger.js'

// 创建axios实例
const api = axios.create({
  baseURL: API_CONFIG.getBaseURL(), // 使用统一配置
  timeout: 30000, // 请求超时时间 - 30秒
  headers: {
    'Content-Type': 'application/json'
  },
  withCredentials: false, // 处理跨域请求
  // 自定义响应数据转换，处理大数精度问题
  transformResponse: [function (data) {
    if (typeof data === 'string') {
      try {
        // 使用正则表达式将JSON中的大数字ID转换为字符串
        // 匹配 "id": 数字 的模式，将数字用引号包裹
        const fixedData = data.replace(
          /"(id|teamId|userId|studentId|questionId|homeworkId|newsId|competitionId)":\s*(\d{15,})/g,
          '"$1":"$2"'
        )
        
        if (data !== fixedData) {
          logger.log('🔢 [BigInt] 检测到大数ID，已转换为字符串格式')
        }
        
        return JSON.parse(fixedData)
      } catch (e) {
        logger.error('❌ [JSON] 解析失败:', e)
        return data
      }
    }
    return data
  }]
})

logger.log('🔧 [API] axios实例已创建，baseURL:', api.defaults.baseURL);

// 判断401错误是否应该触发自动退出登录
function shouldAutoLogoutOn401(error) {
  const url = error.config?.url || ''
  
  // 对于某些特定的API，401错误不应该触发自动退出
  const noAutoLogoutUrls = [
    '/goc/testQuestion/list',  // 题目列表API
    '/goc/testQuestion/search', // 题目搜索API
    '/goc/news/list',          // 新闻列表API
    '/goc/news/search'         // 新闻搜索API
  ]
  
  // 如果是这些API的401错误，不自动退出
  const shouldNotAutoLogout = noAutoLogoutUrls.some(noLogoutUrl => url.includes(noLogoutUrl))
  
  if (shouldNotAutoLogout) {
    logger.log(`🚫 API ${url} 的401错误不触发自动退出登录`)
    return false
  }
  
  // 对于用户相关的关键API，401错误应该触发自动退出
  const criticalAuthUrls = [
    '/goc/user/info',     // 用户信息API
    '/goc/user/profile',  // 用户档案API
    '/goc/user/update'    // 用户更新API
  ]
  
  const isCriticalAuth = criticalAuthUrls.some(criticalUrl => url.includes(criticalUrl))
  
  if (isCriticalAuth) {
    logger.log(`🔑 关键认证API ${url} 的401错误触发自动退出登录`)
    return true
  }
  
  // 默认情况下，401错误不自动退出，让页面自行处理
  logger.log(`⚠️ API ${url} 的401错误暂不触发自动退出，由页面处理`)
  return false
}

// 请求拦截器
api.interceptors.request.use(
  config => {
    // 在发送请求之前做些什么
    const token = localStorage.getItem('token')
    
    logger.log('🌐 [HTTP] ===== 发送请求 =====');
    logger.log('🌐 [HTTP] URL:', config.baseURL + config.url);
    logger.log('🌐 [HTTP] 方法:', config.method?.toUpperCase());
    logger.log('🌐 [HTTP] 当前环境:', process.env.NODE_ENV || 'development');
    logger.log('🌐 [HTTP] baseURL:', config.baseURL);
    logger.log('🌐 [HTTP] 请求路径:', config.url);
    
    // 特别标记退出登录请求
    if (config.url && config.url.includes('/goc/user/logout')) {
      logger.log('🚪🚪🚪 [LOGOUT-REQUEST] 这是一个退出登录请求！ 🚪🚪🚪');
      logger.log('🚪 [LOGOUT-REQUEST] 请求时间:', new Date().toISOString());
      logger.log('🚪 [LOGOUT-REQUEST] 完整URL:', config.baseURL + config.url);
    }
    
    // JWT令牌处理 - 将令牌放在请求头中
    // 检查是否需要跳过认证（如微信状态检查接口）
    if (config.skipAuth) {
      logger.log('🚫 [HTTP] 跳过JWT令牌认证 (skipAuth=true)');
    } else if (token) {
      logger.log('🔍 [HTTP] 准备在请求头中传递JWT令牌...');
      logger.log('🔍 [HTTP] 原始令牌:', token);
      logger.log('🔍 [HTTP] 令牌长度:', token.length);
      
      // 确保headers对象存在
      if (!config.headers) {
        config.headers = {};
        logger.log('🔧 [HTTP] 创建headers对象');
      }
      
      // 将JWT令牌放在Authorization请求头中（纯令牌格式，无Bearer前缀）
      // 根据后端要求：Authorization头的值直接是JWT令牌
      config.headers['Authorization'] = token;  // 纯JWT令牌，不加Bearer前缀
      
      logger.log('🔑 [HTTP] JWT令牌已添加到Authorization请求头（纯令牌格式）');
      logger.log('🔑 [HTTP] Authorization:', config.headers['Authorization']);
      logger.log('🔑 [HTTP] 令牌长度:', token.length);
      logger.log('🔑 [HTTP] 令牌预览:', token.substring(0, 50) + '...');
    } else {
      logger.log('⚠️ [HTTP] 没有JWT令牌，跳过请求头设置');
    }
    
    logger.log('🌐 [HTTP] 最终Headers:', config.headers);
    
    // 最终验证Authorization请求头的设置
    if (token && config.headers) {
      if (config.headers['Authorization']) {
        logger.log('✅ [HTTP] Authorization请求头已正确设置');
        logger.log(`✅ [HTTP] Authorization: ${config.headers['Authorization'].substring(0, 50)}...`);
        logger.log('✅ [HTTP] 格式确认: 纯JWT令牌（无Bearer前缀）');
      } else {
        logger.error('❌ [HTTP] Authorization请求头未设置！');
      }
    } else if (token) {
      logger.error('❌ [HTTP] 错误：有token但请求头未设置！');
      logger.error('❌ [HTTP] token:', token);
      logger.error('❌ [HTTP] config.headers:', config.headers);
    }
    
    if (config.params) {
      logger.log('🌐 [HTTP] Query参数:', config.params);
    }
    if (config.data) {
      logger.log('🌐 [HTTP] Body数据:', config.data);
    }
    
    return config
  },
  error => {
    // 对请求错误做些什么
    logger.error('请求错误:', error)
    return Promise.reject(error)
  }
)

// 响应拦截器
api.interceptors.response.use(
  response => {
    // 2xx 范围内的状态码都会触发该函数
    logger.log('🌐 [HTTP] 收到响应');
    logger.log('🌐 [HTTP] 状态码:', response.status);
    logger.log('🌐 [HTTP] 状态文本:', response.statusText);
    logger.log('🌐 [HTTP] 响应Headers:', response.headers);
    logger.log('🌐 [HTTP] 响应数据:', response.data);
    logger.log('🌐 [HTTP] 完整响应对象:', response);
    
    // 检查响应数据中是否包含令牌过期的错误信息
    if (response.data && response.data.message) {
      const errorMessage = response.data.message
      
      // 检测令牌过期相关的错误消息
      const tokenExpiredPatterns = [
        'claims" is null',
        'jwt expired',
        'token expired',
        'token invalid',
        '令牌过期',
        '登录已过期'
      ]
      
      const isTokenExpired = tokenExpiredPatterns.some(pattern => 
        errorMessage.toLowerCase().includes(pattern.toLowerCase())
      )
      
      if (isTokenExpired) {
        logger.error('🚨 [AUTH] 检测到令牌过期错误:', errorMessage)
        logger.warn('🔐 [AUTH] 登录状态已过期，准备清除本地数据并跳转登录页')
        
        // 显示提示消息
        alert('登录状态已过期，请重新登录')
        
        // 清除本地存储的令牌和用户信息
        localStorage.removeItem('token')
        localStorage.removeItem('userInfo')
        logger.log('✅ [AUTH] 已清除本地令牌和用户信息')
        
        // 跳转到登录页面
        if (window.location.pathname !== '/login') {
          logger.log('🔄 [AUTH] 跳转到登录页面')
          window.location.href = '/login'
        }
        
        // 返回错误数据，让调用方也能处理
        return response.data
      }
    }
    
    // 特别标记退出登录响应
    if (response.config && response.config.url && response.config.url.includes('/goc/user/logout')) {
      logger.log('🚪🚪🚪 [LOGOUT-RESPONSE] 收到退出登录响应！ 🚪🚪🚪');
      logger.log('🚪 [LOGOUT-RESPONSE] 响应时间:', new Date().toISOString());
      logger.log('🚪 [LOGOUT-RESPONSE] 状态码:', response.status);
      logger.log('🚪 [LOGOUT-RESPONSE] 后端确认退出成功！');
    }
    
    // 特殊处理微信二维码接口，需要保留完整response对象来获取headers
    if (response.config && response.config.url && response.config.url.includes('/goc/WeChat/wxLogin')) {
      logger.log('📱 [WECHAT-QR] 微信二维码接口，返回完整response对象');
      return response; // 返回完整对象以便获取headers
    }
    
    // 对于其他接口，保持原有行为
    return response.data
  },
  error => {
    // 超出 2xx 范围的状态码都会触发该函数
    logger.error('🚨 [HTTP] 响应错误:', error);
    logger.error('🚨 [HTTP] 错误详情:', {
      message: error.message,
      code: error.code,
      config: {
        url: error.config?.url,
        method: error.config?.method,
        baseURL: error.config?.baseURL,
        headers: error.config?.headers
      },
      response: error.response ? {
        status: error.response.status,
        statusText: error.response.statusText,
        data: error.response.data,
        headers: error.response.headers
      } : null
    });
    
    // 检查错误响应中是否包含令牌过期的错误信息
    // 检测令牌过期相关的错误消息
    const tokenExpiredPatterns = [
      'claims" is null',
      'jwt expired',
      'token expired',
      'token invalid',
      '令牌过期',
      '登录已过期'
    ]
    
    // 检查多个可能的位置
    let errorMessage = ''
    if (error.response && error.response.data && error.response.data.message) {
      errorMessage = error.response.data.message
    } else if (error.message) {
      errorMessage = error.message
    }
    
    let tokenExpiredHandled = false // 标记是否已处理令牌过期
    
    if (errorMessage) {
      const isTokenExpired = tokenExpiredPatterns.some(pattern => 
        errorMessage.toLowerCase().includes(pattern.toLowerCase())
      )
      
      if (isTokenExpired) {
        logger.error('🚨 [AUTH] 检测到令牌过期错误（错误拦截器）:', errorMessage)
        logger.warn('🔐 [AUTH] 登录状态已过期，准备清除本地数据并跳转登录页')
        
        // 显示提示消息
        alert('登录状态已过期，请重新登录')
        
        // 清除本地存储的令牌和用户信息
        localStorage.removeItem('token')
        localStorage.removeItem('userInfo')
        logger.log('✅ [AUTH] 已清除本地令牌和用户信息')
        
        // 跳转到登录页面
        if (window.location.pathname !== '/login') {
          logger.log('🔄 [AUTH] 跳转到登录页面')
          window.location.href = '/login'
        }
        
        tokenExpiredHandled = true
        
        // 返回拒绝的Promise
        return Promise.reject(error)
      }
    }
    
    if (error.response) {
      // 服务器响应了错误状态码
      switch (error.response.status) {
        case 401: {
          // 如果已经处理过令牌过期，跳过401处理
          if (tokenExpiredHandled) {
            break
          }
          
          // 未授权处理 - 更智能的判断
          logger.error('收到401未授权响应:', {
            url: error.config?.url,
            method: error.config?.method,
            responseData: error.response?.data
          })
          
          // 只有在特定情况下才自动退出登录
          const shouldAutoLogout = shouldAutoLogoutOn401(error)
          
          if (shouldAutoLogout) {
            logger.warn('401错误触发自动退出登录')
            alert('登录状态已过期，请重新登录')
            localStorage.removeItem('token')
            localStorage.removeItem('userInfo')
            // 使用路由跳转而不是强制页面跳转，避免页面卡死
            if (window.location.pathname !== '/login') {
              window.location.href = '/login'
            }
          } else {
            logger.warn('401错误但不触发自动退出，由页面自行处理')
          }
          break
        }
        case 403:
          logger.error('权限不足')
          // 对于权限问题，先静默处理，避免影响用户体验
          break
        case 404:
          logger.error('请求的资源不存在')
          break
        case 500:
          logger.error('服务器内部错误')
          break
        default:
          logger.error('网络错误，请稍后重试')
      }
    } else if (error.request) {
      // 请求已发出但没有收到响应（通常是网络问题）
      logger.error('网络连接失败，请检查网络')
      // 对于网络连接问题，静默处理，让应用使用降级方案
    } else {
      // 其他错误
      logger.error('请求失败：' + error.message)
    }
    
    return Promise.reject(error)
  }
)

export default api 